package im.oen.boot.api.servlet;

import im.oen.boot.api.dispatch.DispatchManager;
import im.oen.boot.api.dispatch.data.UriData;
import im.oen.boot.common.utils.Checker;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * @author Kevin.Xu
 */
public class ApiUriDispatcherServlet extends DispatcherServlet {

    private DispatchManager dispatchManager;

    public ApiUriDispatcherServlet(WebApplicationContext webApplicationContext, ApplicationContext context) {
        super(webApplicationContext);
        this.dispatchManager = new DispatchManager(context);
    }

    @Override
    protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
        UriData data = this.dispatchManager.hasMatch(request);
        if (Checker.isEmpty(data)) {
            super.doService(request, response);
        } else {
            this.doCustomService(request, response, data);
        }
    }

    private void doCustomService(HttpServletRequest request, HttpServletResponse response, UriData data) {
        try {
            HttpServletRequest processedRequest = checkMultipart(request);
            HandlerExecutionChain mappedHandler = this.getHandler(processedRequest);
            boolean hasMappedHandler = Checker.isNotEmpty(mappedHandler);
            if (hasMappedHandler && !this.applyPreHandle(request, response, mappedHandler.getInterceptorList(), mappedHandler.getHandler())) {
                return;
            }
            this.dispatchManager.doService(request, response, data);
        } catch (Exception e) {

        }
    }

    private boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response, List<HandlerInterceptor> interceptors, Object handler) throws Exception {
        if (Checker.isEmpty(interceptors)) {
            return true;
        }
        for (HandlerInterceptor interceptor : interceptors) {
            if (!interceptor.preHandle(request, response, handler)) {
                return false;
            }
        }
        return true;
    }
}
